package city.spring.modules.oldman.controller;

import city.spring.modules.cardinfo.service.CardNumberService;
import city.spring.modules.oldman.entity.OldmanInfoEntity;
import city.spring.modules.oldman.service.OldmanInfoService;
import city.spring.modules.oldman.vo.OldmanVO;
import city.spring.utils.MyBatisUtils;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.util.WebFilenameUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Controller：老人信息
 *
 * @author 侯坤林
 * @date 2020-05-23 04:39:15
 */
@RestController
@RequestMapping("/oldman_info")
public class OldmanInfoController extends ApiController {
    private final OldmanInfoService oldmanInfoService;
    private final CardNumberService cardNumberService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<OldmanInfoEntity, ?>> entityOrderFields;

    public OldmanInfoController(OldmanInfoService oldmanInfoService, CardNumberService cardNumberService) {
        this.oldmanInfoService = oldmanInfoService;
        this.cardNumberService = cardNumberService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(OldmanInfoEntity::getId);
        entityOrderFields.add(OldmanInfoEntity::getOldmanName);
        entityOrderFields.add(OldmanInfoEntity::getCertificateType);
        entityOrderFields.add(OldmanInfoEntity::getCertificate);
        entityOrderFields.add(OldmanInfoEntity::getHeadPortrait);
        entityOrderFields.add(OldmanInfoEntity::getBirthday);
        entityOrderFields.add(OldmanInfoEntity::getSex);
        entityOrderFields.add(OldmanInfoEntity::getTelephone);
        entityOrderFields.add(OldmanInfoEntity::getMaritalStatus);
        entityOrderFields.add(OldmanInfoEntity::getNation);
        entityOrderFields.add(OldmanInfoEntity::getBloodGroup);
        entityOrderFields.add(OldmanInfoEntity::getPoliticalStatus);
        entityOrderFields.add(OldmanInfoEntity::getRetirementCareer);
        entityOrderFields.add(OldmanInfoEntity::getIsCity);
        entityOrderFields.add(OldmanInfoEntity::getIsOutland);
        entityOrderFields.add(OldmanInfoEntity::getOriginalLivingSituation);
        entityOrderFields.add(OldmanInfoEntity::getFamilySize);
        entityOrderFields.add(OldmanInfoEntity::getFamilyAddress);
        entityOrderFields.add(OldmanInfoEntity::getResidenceAddress);
        entityOrderFields.add(OldmanInfoEntity::getPersonnelCategory);
        entityOrderFields.add(OldmanInfoEntity::getReligiousBelief);
        entityOrderFields.add(OldmanInfoEntity::getHobby);
        entityOrderFields.add(OldmanInfoEntity::getCharacterPsychology);
        entityOrderFields.add(OldmanInfoEntity::getDietCharacteristics);
        entityOrderFields.add(OldmanInfoEntity::getEducationLevel);
        entityOrderFields.add(OldmanInfoEntity::getWorkingAbility);
        entityOrderFields.add(OldmanInfoEntity::getSourceEconomy);
        entityOrderFields.add(OldmanInfoEntity::getMedicalInsurance);
        entityOrderFields.add(OldmanInfoEntity::getMedicareCard);
        entityOrderFields.add(OldmanInfoEntity::getStatus);
        entityOrderFields.add(OldmanInfoEntity::getGmtCreate);
        entityOrderFields.add(OldmanInfoEntity::getGmtModified);
    }

    /**
     * 获取全部的 <strong>老人信息</strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault(sort = {"gmtCreate"}) Pageable pageable, OldmanInfoEntity entity) {
        LambdaQueryChainWrapper<OldmanInfoEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }


    /**
     * 分页获取 <strong>老人信息</strong> 列表
     *
     * @param pageable 分页参数信息
     */
    @GetMapping
    public Object list(@PageableDefault(sort = {"gmtCreate"}) Pageable pageable, OldmanInfoEntity entity) {
        LambdaQueryChainWrapper<OldmanInfoEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        Page<OldmanInfoEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
        return success(page);
    }

    /**
     * 测试导出入住申请表
     *
     * @param id       老人ID
     * @param response HTTP写请求
     * @throws Exception 异常
     */
    @GetMapping("{id}/export-check-in")
    public Object exportCheckIn(@PathVariable String id, HttpServletResponse response) throws Exception {
        OldmanInfoEntity oldmanInfoEntity = oldmanInfoService.getById(id);
        if (oldmanInfoEntity != null) {
            Map<String, Object> params = new HashMap<>();
            // 老人信息
            params.put("people", oldmanInfoEntity);
            // 家属列表
            params.put("families", new ArrayList<>());
            // 设置内容类型
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            // 设置默认下载文件名称
            response.setHeader("content-disposition", WebFilenameUtils.disposition(oldmanInfoEntity.getOldmanName() + ".xlsx"));
            // 模板示例： http://doc.wupaas.com/docs/easypoi/easypoi-1c10lgqkb9ton

            // 调用导出方法
            TemplateExportParams templateExportParams = new TemplateExportParams("templates/check-in.xlsx");
            Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams, params);

            /// ClassPathResource resource = new ClassPathResource("templates/check-in.xlsx");
            /// MyXWPFDocument document = new MyXWPFDocument(resource.getInputStream());
            /// WordExportUtil.exportWord07(document, params);

            // 把结果流写入HTTP response中
            ServletOutputStream out = response.getOutputStream();
            workbook.write(out);
            out.flush();
        }
        return null;
    }

    /**
     * 获取可以使用的用户列表（前端选择用户时使用的用户列表）
     *
     * @param pageable 分页信息
     */
    @GetMapping("selectList")
    public Object selectUserList(@PageableDefault(sort = {"gmtCreate"}) Pageable pageable, OldmanInfoEntity entity) {
        LambdaQueryChainWrapper<OldmanInfoEntity> lambdaQuery = buildLambdaQuery(entity);
        lambdaQuery.select(OldmanInfoEntity::getId, OldmanInfoEntity::getOldmanName,
                OldmanInfoEntity::getCertificate,
                OldmanInfoEntity::getSex,
                OldmanInfoEntity::getMedicareCard,
                OldmanInfoEntity::getNation,
                OldmanInfoEntity::getEducationLevel,
                OldmanInfoEntity::getReligiousBelief,
                OldmanInfoEntity::getMaritalStatus,
                OldmanInfoEntity::getOriginalLivingSituation,
                OldmanInfoEntity::getMedicalInsurance,
                OldmanInfoEntity::getSourceEconomy,
                OldmanInfoEntity::getTelephone,
                OldmanInfoEntity::getBirthday);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        Page<OldmanInfoEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
        for (OldmanInfoEntity record : page.getRecords()) {
            record.setBirthdayString(record.getCertificate().substring(6, 10) + "年" + record.getCertificate().substring(10, 12) + "月" + record.getCertificate().substring(12, 14) + "日");
        }
        return success(page);
    }


    /**
     * 获取 <strong>老人信息</strong> 列表
     */
    @GetMapping("birth/{datevalue}")
    public Object birthList(@PathVariable String datevalue) {
        return success(oldmanInfoService.getBirthList(datevalue));
    }

    /**
     * 获取一个 <strong>老人信息</strong>
     *
     * @param id 主键ID
     */
    @GetMapping("{id}")
    public Object info(@PathVariable String id) {
        return success(oldmanInfoService.getOldmanInfo(id));
    }

    /**
     * 修改一个 <strong>老人信息</strong>
     *
     * @param id     主键ID
     * @param entity 修改后的信息
     */
    @PutMapping("{id}")
    public Object update(@PathVariable String id, @RequestBody OldmanVO entity) {
        entity.setId(id);
        oldmanInfoService.updateOldmanInfo(entity);

        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 删除一个 <strong>老人餐饮费</strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        oldmanInfoService.deleteOldmanInfo(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * @param id
     * @param entity
     * @return
     */
//    @PutMapping("/cardSet/{id}")
//    public Object cardSet(@PathVariable String id, @RequestBody OldmanVO entity) {
//        entity.setId(id);
//        oldmanInfoService.updateOldmanInfo(entity);
//        // 把老人表更新的物理卡号，同时更新到卡表里（card_number ）  老人id与对应的卡id相同，getById获取人员对应的卡记录
//        CardNumberEntity cardNumberEntity = cardNumberService.getById(entity.getId());
//        cardNumberEntity.setPhysicsCard(entity.getPhysicsCard());
//        return new ResponseEntity<>(HttpStatus.OK);
//    }

    /**
     * 老人退住
     *
     * @param id 老人ID
     * @return
     */
    @PostMapping("{id}/retreat")
    public Object retreat(@PathVariable String id) {
        oldmanInfoService.retreat(id);
        return success(null);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<OldmanInfoEntity> buildLambdaQuery(OldmanInfoEntity entity) {
        LambdaQueryChainWrapper<OldmanInfoEntity> lambdaQuery = oldmanInfoService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), OldmanInfoEntity::getId, entity.getId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getOldmanName()), OldmanInfoEntity::getOldmanName, entity.getOldmanName());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getCertificateType()), OldmanInfoEntity::getCertificateType, entity
                .getCertificateType());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getCertificate()), OldmanInfoEntity::getCertificate, entity.getCertificate());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getHeadPortrait()), OldmanInfoEntity::getHeadPortrait, entity.getHeadPortrait());
        lambdaQuery.eq(entity.getBirthday() != null, OldmanInfoEntity::getBirthday, entity.getBirthday());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getSex()), OldmanInfoEntity::getSex, entity.getSex());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getTelephone()), OldmanInfoEntity::getTelephone, entity.getTelephone());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getMaritalStatus()), OldmanInfoEntity::getMaritalStatus, entity.getMaritalStatus());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getNation()), OldmanInfoEntity::getNation, entity.getNation());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getBloodGroup()), OldmanInfoEntity::getBloodGroup, entity.getBloodGroup());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getPoliticalStatus()), OldmanInfoEntity::getPoliticalStatus, entity
                .getPoliticalStatus());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getRetirementCareer()), OldmanInfoEntity::getRetirementCareer, entity
                .getRetirementCareer());
        lambdaQuery.eq(entity.getIsCity() != null, OldmanInfoEntity::getIsCity, entity.getIsCity());
        lambdaQuery.eq(entity.getIsOutland() != null, OldmanInfoEntity::getIsOutland, entity.getIsOutland());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getOriginalLivingSituation()), OldmanInfoEntity::getOriginalLivingSituation, entity
                .getOriginalLivingSituation());
        lambdaQuery.eq(entity.getFamilySize() != null, OldmanInfoEntity::getFamilySize, entity.getFamilySize());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getFamilyAddress()), OldmanInfoEntity::getFamilyAddress, entity.getFamilyAddress());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getResidenceAddress()), OldmanInfoEntity::getResidenceAddress, entity
                .getResidenceAddress());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getPersonnelCategory()), OldmanInfoEntity::getPersonnelCategory, entity
                .getPersonnelCategory());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getReligiousBelief()), OldmanInfoEntity::getReligiousBelief, entity
                .getReligiousBelief());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getHobby()), OldmanInfoEntity::getHobby, entity.getHobby());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getCharacterPsychology()), OldmanInfoEntity::getCharacterPsychology, entity
                .getCharacterPsychology());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getDietCharacteristics()), OldmanInfoEntity::getDietCharacteristics, entity
                .getDietCharacteristics());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getEducationLevel()), OldmanInfoEntity::getEducationLevel, entity
                .getEducationLevel());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getWorkingAbility()), OldmanInfoEntity::getWorkingAbility, entity
                .getWorkingAbility());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getSourceEconomy()), OldmanInfoEntity::getSourceEconomy, entity.getSourceEconomy());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getMedicalInsurance()), OldmanInfoEntity::getMedicalInsurance, entity
                .getMedicalInsurance());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getMedicareCard()), OldmanInfoEntity::getMedicareCard, entity.getMedicareCard());
        lambdaQuery.eq(entity.getStatus() != null, OldmanInfoEntity::getStatus, entity.getStatus());
        lambdaQuery.eq(entity.getGmtCreate() != null, OldmanInfoEntity::getGmtCreate, entity.getGmtCreate());
        lambdaQuery.eq(entity.getGmtModified() != null, OldmanInfoEntity::getGmtModified, entity.getGmtModified());
        return lambdaQuery;
    }

    /**
     * 查找老人状态为正式入住、试入住的老人
     *
     * @return
     */
    @GetMapping("/oldmanInfoByStatus")
    public Object oldmanInfoByStatus() {
        return success(oldmanInfoService.oldmanInfoByStatus());
    }

    /**
     * 获取已进行入院缴费的老人列表，用于之后的月度缴费
     *
     * @return
     */
    @GetMapping("/getFirstPayOldList")
    public Object getFirstPayOldList() {
        return success(oldmanInfoService.getFirstPayOldList());
    }

    /**
     * 入院且没有退院的老人，筛选截止到本月之前有未交费的老人列表
     *
     * @return
     */
    @GetMapping("/getArrearsOldList")
    public Object getArrearsOldList() {
        return success(oldmanInfoService.getArrearsOldList());
    }


    /**
     * 修改老人状态从试入住转为正式入住
     *
     * @param id
     * @param entity
     * @return
     */
    @PutMapping("/transferCheckin/{id}")
    public Object transferCheckin(@PathVariable String id, @RequestBody OldmanInfoEntity entity) {
        oldmanInfoService.transferCheckin(id, entity);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
